﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualBasic.Devices;
using Tzx.TUpdater.Utilities;

namespace Tzx.TUpdater
{
    /// <summary>
    /// 
    /// </summary>
    internal class AppGlobal
    {
        #region 文本

        /// <summary>
        /// 本应用程序版本信息
        /// </summary>
        public static string AppVersion
        {
            get
            {
                if (_appVersion == null)
                {
                    Assembly assembly = Assembly.GetExecutingAssembly();
                    if (assembly != null)
                    {
                        AssemblyName assemblyName = assembly.GetName();
                        if (assemblyName != null)
                        {
                            _appVersion = string.Format("{0}", assemblyName.Version.ToString());
                        }
                    }
                }
                return string.Format("{0}", _appVersion);
            }
        }
        private static string _appVersion;

        /// <summary>
        /// 本应用程序名称版本文字
        /// </summary>
        public static string AppNameText
        {
            get { return "自动更新" + "【" + AppVersion + "】"; }
        }

        /// <summary>
        /// 本应用程序GUID
        /// </summary>
        public const string AppGuid = "250fcc1e-979d-406d-bbe0-3711f84ab595";

        #endregion

        #region EXE文件名称与路径

        /// <summary>
        /// 可执行文件包含扩展名的全名，如“Updater.exe”
        /// </summary>
        internal static string ExeNameAndExt
        {
            get
            {
                string exePathName = Application.ExecutablePath;
                string s = exePathName.Substring(exePathName.LastIndexOf('\\'));
                return s.TrimStart('\\', '/');
            }
        }

        /// <summary>
        /// 可执行文件仅文件名，如“Updater”
        /// </summary>
        internal static string ExeName
        {
            get
            {
                string s = ExeNameAndExt.Substring(0, ExeNameAndExt.LastIndexOf('.'));
                return s.Trim('\\', '/');
            }
        }

        /// <summary>
        /// EXE可执行文件所在目录
        /// </summary>
        public static string ExeDirectory
        {
            get
            {
                if (_exeDirectory == null)
                {
                    _exeDirectory = Application.StartupPath;
                }
                return _exeDirectory;
            }
        }
        private static string _exeDirectory;

        /// <summary>
        /// 自身升级EXE文件名
        /// </summary>
        internal static string ExeSelfUpdateFileName
        {
            get
            {
                string gid = string.Format("{0}", AppGuid).Trim('{', '}').Replace("-", "");
                return string.Format("{0}.{1}.rename", ExeNameAndExt, gid);
            }
        }

        #endregion

        #region 客户程序

        /// <summary>
        /// 临时目录路径
        /// </summary>
        internal static string TempDirectoryPath
        {
            get
            {
                string temp = string.Format("{0}", Environment.GetEnvironmentVariable("Temp"));
                string tempUpdatePath = temp.TrimEnd('\\') + "\\" + "_" + IniApplication.Trim() + "_" + "\\";
                return tempUpdatePath;
            }
        }

        /// <summary>
        /// 主应用程序名称
        /// </summary>
        internal static string ApplicationName
        {
            get
            {
                string applicationName = string.Empty;
                string appFullName = IniApplication.Trim();
                int extIndex = appFullName.LastIndexOf('.');
                if (extIndex > 0)
                {
                    applicationName = appFullName.Substring(0, extIndex).TrimEnd('.').Trim('\\', '/');
                }
                return applicationName;
            }
        }

        #endregion

        #region tupdater.xml

        /// <summary>
        /// LocalXml文件路径和名称(全称)
        /// </summary>
        internal static string XmlPathName_LocalFile
        {
            get
            {
                string s = Application.StartupPath.TrimEnd('\\', '/') + "\\" + ExeName + ".xml"; //LocalXml
                return s.TrimStart('\\', '/');
            }
        }

        /// <summary>
        /// LocalXml文件路径和名称(全称)的临时备份文件
        /// </summary>
        internal static string XmlPathName_LocalFile_Bak
        {
            get
            {
                string s = Application.StartupPath.TrimEnd('\\', '/') + "\\" + ExeName + ".xml.bak"; //LocalXml
                return s.TrimStart('\\', '/');
            }
        }

        /// <summary>
        /// ServerXml文件路径和名称(全称)
        /// </summary>
        internal static string XmlPathName_ServerFile
        {
            get
            {
                //临时文件目录
                string serverXmlFile = TempDirectoryPath.Trim('\\', '/') + "\\" + ExeName.Trim('\\', '/') + ".xml";  //ServerXml
                return serverXmlFile;
            }
        }

        /// <summary>
        /// ServerXml文件Url路径
        /// </summary>
        internal static string XmlPathName_ServerUrl
        {
            get
            {
                string serverXmlUrl;
                string xmlFile = ExeName + ".xml";
                string url = IniUpdaterUrl.TrimEnd('/');
                if (!url.EndsWith(xmlFile, StringComparison.InvariantCultureIgnoreCase))
                {
                    serverXmlUrl = string.Format("{0}/{1}", url, xmlFile);
                }
                else
                {
                    serverXmlUrl = string.Format("{0}", url);
                }
                return serverXmlUrl;
            }
        }

        /// <summary>
        /// 检查与初始化 tupdater.xml 更新文件
        /// </summary>
        internal static void InitializeLocalXmlFile()
        {
            if (!File.Exists(XmlPathName_LocalFile))
            {
                XmlConfig.CreateBlankUpdateFile(XmlPathName_LocalFile, "暂无更新信息");
            }
        }

        #endregion

        #region tupdater.ini

        private const string IniSectionQUpdater                 = "QUpdater";
        private const string IniKeyQUpdaterAutoNext             = "AutoNext";
        private const string IniKeyQUpdaterCheckLostFile        = "CheckLostFile";
        private const string IniKeyQUpdaterMode_Key             = "Mode";
        private const string IniKeyQUpdaterMode_Value_Silence   = "Silence";
        
        private const string IniSectionUpdateinfo               = "UPDATEINFO";
        internal const string IniKeyUpdateinfoListURL           = "ListURL";

        private const string IniSectionApplication              = "APPLICATION";
        private const string IniKeyApplication                  = "Application";
        private const string IniKeyApplicationName              = "Name";

        /// <summary>
        /// Ini属性 - AutoNext
        /// </summary>
        /// <returns></returns>
        internal static bool IniAutoNext
        {
            get
            {
                string autoNext = IniHelper.ReadIniData(IniSectionQUpdater, IniKeyQUpdaterAutoNext, string.Empty);
                autoNext = autoNext.ToLower();
                bool isAutoNext = Array.IndexOf(new string[] {"1", "true", "yes"}, autoNext) > -1;
                return isAutoNext;
            }
            set
            {
                //设置Ini - 是否自动进入下一步
                bool isAutoNext = value;
                IniHelper.WriteIniData(IniSectionQUpdater, IniKeyQUpdaterAutoNext, isAutoNext.ToString());
            }
        }

        /// <summary>
        /// Ini属性 - CheckLostFile
        /// </summary>
        /// <returns></returns>
        internal static bool IniCheckLostFile
        {
            get
            {
                string checkLostFile = IniHelper.ReadIniData(IniSectionQUpdater, IniKeyQUpdaterCheckLostFile, string.Empty);
                checkLostFile = string.Format("{0}", checkLostFile).Trim().ToLower();
                bool isCheckLostFile = Array.IndexOf(new string[] { "1", "true", "yes" }, checkLostFile) > -1;
                return isCheckLostFile;
            }
            set
            {
                bool isCheckLostFile = value;
                IniHelper.WriteIniData(IniSectionQUpdater, IniKeyQUpdaterCheckLostFile, isCheckLostFile.ToString());
            }
        }

        /// <summary>
        /// Ini属性 - Mode
        /// </summary>
        /// <returns></returns>
        internal static string IniMode
        {
            get
            {
                string mode = IniHelper.ReadIniData(IniSectionQUpdater, IniKeyQUpdaterMode_Key, string.Empty);
                return mode;
            }
            set
            {
                string mode = value;
                IniHelper.WriteIniData(IniSectionQUpdater, IniKeyQUpdaterMode_Key, mode);
            }
        }

        /// <summary>
        /// Ini属性 - Mode是否为静默安装
        /// </summary>
        /// <returns></returns>
        internal static bool IniMode_IsSilence
        {
            get
            {
                string mode = IniMode;
                return String.Compare(mode, IniKeyQUpdaterMode_Value_Silence, StringComparison.InvariantCultureIgnoreCase) == 0;
            }
            set
            {
                bool modeIsSilence = value;
                if (modeIsSilence)
                {
                    IniHelper.WriteIniData(IniSectionQUpdater, IniKeyQUpdaterMode_Key, IniKeyQUpdaterMode_Value_Silence);
                }
            }
        }

        /// <summary>
        /// Ini属性 - UpdaterUrl
        /// </summary>
        /// <returns></returns>
        internal static string IniUpdaterUrl
        {
            get
            {
                string url = IniHelper.ReadIniData(IniSectionUpdateinfo, IniKeyUpdateinfoListURL, string.Empty);//url
                return url;
            }
            set
            {
                //设置Ini - 更新Url地址
                string url = string.Format("{0}", value).Trim();
                IniHelper.WriteIniData(IniSectionUpdateinfo, IniKeyUpdateinfoListURL, url);//url
            }
        }

        /// <summary>
        /// Ini属性 - Application
        /// </summary>
        /// <returns></returns>
        internal static string IniApplication
        {
            get
            {
                string application = IniHelper.ReadIniData(IniSectionApplication, IniKeyApplication, string.Empty);
                application = string.Format("{0}", application).Trim();
                return application;
            }
            set
            {
                //设置Ini - 主程序Exe文件名(不含路径)
                string application = value;
                IniHelper.WriteIniData(IniSectionApplication, IniKeyApplication, application);
            }
        }

        /// <summary>
        /// Ini属性 - ApplicationName
        /// </summary>
        /// <returns></returns>
        internal static string IniApplicationName
        {
            get
            {
                string applicationName = IniHelper.ReadIniData(IniSectionApplication, IniKeyApplicationName, string.Empty);
                return applicationName;
            }
            set
            {
                //设置Ini - 主程序名称(汉字)
                string applicationName = value;
                IniHelper.WriteIniData(IniSectionApplication, IniKeyApplicationName, applicationName);
            }
        }

        /// <summary>
        /// 检查与初始化 tupdater.exe.ini 配置文件
        /// </summary>
        internal static void InitializeIniFile()
        {
            if (!InitializeIniFileOk)
            {
                //AutoNext,默认true
                if (string.IsNullOrEmpty(IniHelper.ReadIniData(IniSectionQUpdater, IniKeyQUpdaterAutoNext, null)))
                {
                    IniHelper.WriteIniData(IniSectionQUpdater, 
                        IniKeyQUpdaterAutoNext, 
                        string.Format("{0}",false.ToString())  //默认不自动进入下一步
                        );
                }

                //CheckLostFile,默认true
                if (string.IsNullOrEmpty(IniHelper.ReadIniData(IniSectionQUpdater, IniKeyQUpdaterCheckLostFile, null)))
                {
                    IniHelper.WriteIniData(IniSectionQUpdater, 
                        IniKeyQUpdaterCheckLostFile,
                        string.Format("{0}", true.ToString())  //默认检查丢失文件
                        );
                }

                //Mode,Silence
                if (string.IsNullOrEmpty(IniHelper.ReadIniData(IniSectionQUpdater, IniKeyQUpdaterMode_Key, null)))
                {
                    //注释
                    //IniHelper.WriteIniData(IniSectionQUpdater,
                    //    ";" + IniKeyQUpdaterMode_Key,
                    //    string.Format("{0}/{1}",IniKeyQUpdaterMode_Value_Silence,"")
                    //    );

                    //配置
                    IniHelper.WriteIniData(IniSectionQUpdater,
                        IniKeyQUpdaterMode_Key,
                        //string.Format("{0}", string.Empty
                        string.Format(";{0}", IniKeyQUpdaterMode_Value_Silence  //默认不静默安装
                        ));
                }

                //ListURL,需用户输入
                if (string.IsNullOrEmpty(IniHelper.ReadIniData(IniSectionUpdateinfo, IniKeyUpdateinfoListURL, null))) //url
                {
                    IniHelper.WriteIniData(IniSectionUpdateinfo, IniKeyUpdateinfoListURL, string.Empty); //url
                }

                //Application,获得父进程
                if (string.IsNullOrEmpty(IniHelper.ReadIniData(IniSectionApplication, IniKeyApplication, null)))
                {
                    string applicationName = string.Empty;
                    Process parent = ProcessHelper.GetParent(Process.GetCurrentProcess());
                    if (parent != null)
                    {
                        string parentExePathName = parent.MainModule.FileName;
                        if (!string.IsNullOrEmpty(parentExePathName))
                        {
                            applicationName = parentExePathName.Substring(parentExePathName.LastIndexOf('\\')).Trim('\\', '/');
                        }
                    }
                    IniHelper.WriteIniData(IniSectionApplication, IniKeyApplication, applicationName);
                }

                //Name
                if (string.IsNullOrEmpty(IniHelper.ReadIniData(IniSectionApplication, IniKeyApplicationName, null)))
                {
                    IniHelper.WriteIniData(IniSectionApplication, IniKeyApplicationName, string.Empty);
                }

                //
                InitializeIniFileOk = true;
            }
        }
        private static bool InitializeIniFileOk = false;

        #endregion

        #region tupdater.log

        /// <summary>
        /// 
        /// </summary>
        internal static void Log(params string[] logTexts)
        {
            LogFile logFile = LogFile.Instance(ExeDirectory.TrimEnd('\\') + '\\', ExeName.TrimEnd('.') + ".log");
            logFile.LogText(logTexts);
        }

        /// <summary>
        /// 
        /// </summary>
        internal static void Log(Exception ex)
        {
            LogFile logFile = LogFile.Instance(ExeDirectory.TrimEnd('\\') + '\\', ExeName.TrimEnd('.') + ".log");
            logFile.LogException(ex);
        }

        /// <summary>
        /// 日志文件超大检查
        /// </summary>
        internal static void LogFileCheck()
        {
            //
            const long MaxFileSizeByte = 1024 * 1024 * 5; //5M

            //
            string file = string.Format("{0}\\{1}.log", ExeDirectory.TrimEnd('\\'), ExeName.TrimEnd('.'));
            FileInfo fi = new FileInfo(file);
            if (!fi.Exists)
            {
                return;
            }
            if (fi.Length > MaxFileSizeByte)
            {
                //重命名现log文件
                Microsoft.VisualBasic.Devices.Computer c = new Computer();
                string newName = ExeName.TrimEnd('.') + "_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".log";
                c.FileSystem.RenameFile(file, newName);
            }


        }

        /// <summary>
        /// 调试时记录日志
        /// </summary>
        internal static void LogDebug(params string[] logTexts)
        {
#if DEBUG
            //调试
            Log(logTexts);
#else
            //发行时
#endif
        }

        #endregion

    }
}